﻿// ***** Guidance generated code © Catharsis ***** //

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Web.Mvc;

using Castle.DynamicProxy;

using $prjsn$.Entity;

using ProjectBase.Core;
using ProjectBase.Core.Tools.Import;

namespace $safeprojectname$
{
    [Serializable]
    public class AuditableFilter : IInterceptor
    {
        #region AOP
        public virtual void Intercept(IInvocation invocation)
        {
            if (!DoApplyFilter(invocation))
            {
                invocation.Proceed();
                return;
            }

            // pre
            var previous = BeforeExecuting(invocation);

            // BindEntity
            invocation.Proceed();

            // post
            AfterExecuted(invocation, previous);
        }

        protected virtual bool DoApplyFilter(IInvocation invocation)
        {
            // not of our interest
            if (invocation.Arguments.IsEmpty()) // first must be (entity) in place
            {
                return false;
            }

            // is it IAuditable?
            return invocation.Arguments[0] is IAuditable;
        }

        protected virtual IAuditable BeforeExecuting(IInvocation invocation)
        {
            var entity = invocation.Arguments[0] as IAuditable;
            return entity.Clone() as IAuditable;
        }

        protected virtual void AfterExecuted(IInvocation invocation, IAuditable previous)
        {
            var entity = invocation.Arguments[0] as IAuditable;

            // TODO
            // AuditChanges(entity, previous);
        }
        #endregion AOP

        #region Audit
        //protected virtual void AuditChanges(IAuditable currentState, IAuditable previousState)
        //{
        //    var entity = currentState as IDimension;
        //    if (entity.IsNull())
        //    {
        //        return; // nothing to do here
        //    }

        //    // new Dimension
        //    if (entity.IsTransient())
        //    {
        //        entity.AppendAudit("EntityCreation", "Inserted");
        //        foreach (var codeMapper in entity.CodeMappers)
        //        {
        //            entity.AppendAudit("CollectionItemInserted", "CodeMapper.Code", codeMapper.Code);
        //        }
        //        return;
        //    }

        //    // is there previous
        //    var previous = previousState as IDimension;
        //    if (previous.IsNull())
        //    {
        //        return;
        //    }

        //    CheckDimensionChanges(entity, previous);
        //    CheckCodeMapperChanges(entity, previous);
        //}

        //protected virtual void CheckDimensionChanges(IDimension currentState, IDimension previousState)
        //{
        //    var entity = currentState;
        //    var previous = previousState;

        //    entity.CheckPropertyChange((auditable) => auditable.Code, previous);
        //    entity.CheckPropertyChange((auditable) => auditable.Name, previous);
        //    entity.CheckPropertyChange((auditable) => auditable.ValidTo, previous);
        //    entity.CheckPropertyChange((auditable) => auditable.Active, previous);
        //}

        //protected virtual void CheckCodeMapperChanges(IDimension currentState, IDimension previousState)
        //{
        //    var entity = currentState;
        //    var previous = previousState;
        //    foreach (var codeMapper in entity.CodeMappers)
        //    {
        //        var item = codeMapper;
        //        var old = previous.CodeMappers.SingleOrDefault(c => c.ID.Equals(item.ID));
        //        if (old.IsNull())
        //        {
        //            entity.AppendAudit("CollectionItemAdded", "CodeMapper.Code", item.Code);
        //            continue;
        //        }
        //        if (item.ReActivate)
        //        {
        //            entity.AppendAudit("CollectionItemReActivated", "CodeMapper.ValidTo [{0}]".FormatWith(item.Code), item.ValidTo, old.ValidTo);
        //            continue;
        //        }
        //        if (!item.IsActive
        //            && old.IsActive)
        //        {
        //            entity.AppendAudit("CollectionItemDeActivated", "CodeMapper.ValidTo [{0}]".FormatWith(item.Code), item.ValidTo, old.ValidTo);
        //        }
        //    }
        //}

        #endregion Audit
    }
}